﻿Imports System.Threading

Namespace Global.Runa.UI.Threading

    Friend Class DispatcherOperationEvent

        Private _event As ManualResetEvent
        Private _eventClosed As Boolean
        Private _operation As DispatcherOperation
        Private _timeout As TimeSpan

        Public Sub New(ByVal op As DispatcherOperation, ByVal timeout As TimeSpan)
            Me._operation = op
            Me._timeout = timeout
            Me._event = New ManualResetEvent(False)
            Me._eventClosed = False
            SyncLock Me.DispatcherLock
                AddHandler Me._operation.Aborted, New EventHandler(AddressOf Me.OnCompletedOrAborted)
                AddHandler Me._operation.Completed, New EventHandler(AddressOf Me.OnCompletedOrAborted)
                If ((Me._operation.Status <> DispatcherOperationStatus.Pending) AndAlso (Me._operation.Status <> DispatcherOperationStatus.Executing)) Then
                    Me._event.Set()
                End If
            End SyncLock
        End Sub

        Private Sub OnCompletedOrAborted(ByVal sender As Object, ByVal e As EventArgs)
            SyncLock Me.DispatcherLock
                If Not Me._eventClosed Then
                    Me._event.Set()
                End If
            End SyncLock
        End Sub

        Public Sub WaitOne()
#If WINDOWS_PHONE Or NETFX_CORE Then
            Me._event.WaitOne(Me._timeout)
#Else
            Me._event.WaitOne(Me._timeout, False)
#End If
            SyncLock Me.DispatcherLock
                If Not Me._eventClosed Then
                    RemoveHandler Me._operation.Aborted, New EventHandler(AddressOf Me.OnCompletedOrAborted)
                    RemoveHandler Me._operation.Completed, New EventHandler(AddressOf Me.OnCompletedOrAborted)
#If Not NETFX_CORE Then
                    Me._event.Close()
#End If
                    Me._eventClosed = True
                End If
            End SyncLock
        End Sub

        Private ReadOnly Property DispatcherLock As Object
            Get
                Return Me._operation.m_DispatcherLock
            End Get
        End Property

    End Class

End Namespace